package org.agile2soft.nexoma.core.ioc;

import org.agile2soft.nexoma.core.controller.UserController;
import org.agile2soft.nexoma.core.controller.ProfileController;
import org.agile2soft.nexoma.core.controller.ServiceController;
import org.agile2soft.nexoma.core.controller.ServiceOptionController;
import org.agile2soft.nexoma.core.controller.ServicesGroupController;
import org.agile2soft.nexoma.core.controller.InternalUserController;
import org.agile2soft.nexoma.core.controller.impl.UserControllerImpl;
import org.agile2soft.nexoma.core.controller.impl.ProfileControllerImpl;
import org.agile2soft.nexoma.core.controller.impl.ServiceControllerImpl;
import org.agile2soft.nexoma.core.controller.impl.ServiceOptionControllerImpl;
import org.agile2soft.nexoma.core.controller.impl.ServicesGroupControllerImpl;
import org.agile2soft.nexoma.core.controller.impl.InternalUserControllerImpl;
import org.agile2soft.nexoma.core.dao.UserDAO;
import org.agile2soft.nexoma.core.dao.ProfileDAO;
import org.agile2soft.nexoma.core.dao.ServiceDAO;
import org.agile2soft.nexoma.core.dao.ServiceOptionDAO;
import org.agile2soft.nexoma.core.dao.ServicesGroupDAO;
import org.agile2soft.nexoma.core.dao.InternalUserDAO;
import org.agile2soft.nexoma.core.dao.hibernate.InternalUserDAOImpl;
import org.agile2soft.nexoma.core.dao.hibernate.ProfileDAOImpl;
import org.agile2soft.nexoma.core.dao.hibernate.UserDAOImpl;
import org.agile2soft.nexoma.core.dao.hibernate.ServiceDAOImpl;
import org.agile2soft.nexoma.core.dao.hibernate.ServiceOptionDAOImpl;
import org.agile2soft.nexoma.core.dao.hibernate.ServicesGroupDAOImpl;
import org.agile2soft.nexoma.expedient.ioc.ExpedientConfiguration;
import org.hibernate.SessionFactory;
import org.springframework.config.java.annotation.Bean;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.config.java.annotation.ExternalBean;
import org.springframework.config.java.annotation.Import;
import org.springframework.config.java.annotation.Lazy;

import br.com.arsmachina.dao.hibernate.ioc.PersistenceConfiguration;

/**
 * Main configuration class for Spring JavaConfig. It just imports the other configuration classes.
 *
 * @author Antonio M. Fernandez Rodriguez
 */
@Configuration(defaultLazy = Lazy.TRUE)
@Import( { PersistenceConfiguration.class, ExpedientConfiguration.class } )
public class CoreConfiguration {


    /**
     * Declares a <code>sessionFactory</code> bean, defined elsewhere.
     *
     * @return a {@link SessionFactory}.
     */
    @ExternalBean
    public SessionFactory sessionFactory() {
        return null;
    }

    /**
     * Declares the <code>userDAO</code> bean.
     *
     * @return a {@link InternalUserDAO}.
     */
    @Bean
    public InternalUserDAO userDAO() {
        return new InternalUserDAOImpl(sessionFactory());
    }

    /**
     * Declares the <code>userController</code> bean.
     *
     * @return a {@link InternalUserController}.
     */
    @Bean
    public InternalUserController userController() {
        return new InternalUserControllerImpl(userDAO());
    }

    /**
     * Declares the <code>userDAO</code> bean.
     *
     * @return a {@link InternalUserDAO}.
     */
    @Bean
    public UserDAO citizenDAO() {
        return new UserDAOImpl(sessionFactory());
    }

    /**
     * Declares the <code>userController</code> bean.
     *
     * @return a {@link InternalUserController}.
     */
    @Bean
    public UserController citizenController() {
        return new UserControllerImpl(citizenDAO());
    }


    /**
     * Declares the <code>service</code> bean.
     *
     * @return a {@link ServiceDAO}.
     */
    @Bean
    public ServiceDAO serviceDAO() {
        return new ServiceDAOImpl(sessionFactory());
    }

    /**
     * Declares the <code>serviceController</code> bean.
     *
     * @return a {@link serviceController}.
     */
    @Bean
    public ServiceController serviceController() {
        return new ServiceControllerImpl(serviceDAO());
    }
    /**
     * Declares the <code>service grup</code> bean.
     *
     * @return a {@link ServicesGroupDAO}.
     */
    @Bean
    public ServicesGroupDAO servicesGroupDAO() {
        return new ServicesGroupDAOImpl(sessionFactory());
    }

    /**
     * Declares the <code>serviceController</code> bean.
     *
     * @return a {@link serviceController}.
     */
    @Bean
    public ServicesGroupController servicesGroupController() {
        return new ServicesGroupControllerImpl(servicesGroupDAO());
    }


    @Bean
    public ServiceOptionDAO serviceOptionDAO() {
        return new ServiceOptionDAOImpl(sessionFactory());
    }

    /**
     * Declares the <code>serviceController</code> bean.
     *
     * @return a {@link serviceController}.
     */
    @Bean
    public ServiceOptionController serviceOptionController() {
        return new ServiceOptionControllerImpl(serviceOptionDAO());
    }
    /**
     * Declares the <code>profile</code> bean.
     *
     * @return a {@link ProfileDAO}.
     */
    @Bean
    public ProfileDAO profilesDAO() {
        return new ProfileDAOImpl(sessionFactory());
    }

    /**
     * Declares the <code>profilesController</code> bean.
     *
     * @return a {@link ProfilesController}.
     */
    @Bean
    public ProfileController profileController() {
        return new ProfileControllerImpl(profilesDAO());
    }
}
